﻿using System.Collections.Generic;
using System.Linq;

namespace dPet.Domain.Services.Implementation
{
	using dPet.Domain.Models;
	using dPet.Domain.Repositories;
	using Hangerd;

	public class ServingDomainService : IServingDomainService
	{
		private readonly IServiceSKUPropertyRepository _serviceSKUPropertyRepository;

		public ServingDomainService(IServiceSKUPropertyRepository serviceSKUPropertyRepository)
		{
			_serviceSKUPropertyRepository = serviceSKUPropertyRepository;
		}

		public void GenerateServiceItemSKU(ServiceItem serviceItem)
		{
			var propertyValuesSet = new List<ServiceSKUPropertyValue[]>();
			var combinedSetLength = 1;

			if (serviceItem.SKUProperties != null)
			{
				if (serviceItem.SKUProperties.Count > 3)
				{
					throw new HangerdException("SKU属性过多，不得大于3个，请重新配置");
				}

				//获取SKU属性值数量大于1的属性值列表集合
				foreach (var property in serviceItem.SKUProperties)
				{
					var skuProperty = _serviceSKUPropertyRepository.Get(property.Id, false, p => p.Values);

					if (skuProperty != null && skuProperty.Values != null && skuProperty.Values.Count > 0)
					{
						combinedSetLength *= skuProperty.Values.Count;

						propertyValuesSet.Add(skuProperty.Values.ToArray());
					}
				}
			}

			//没有足够属性值的时候生成一条无属性值SKU
			if (propertyValuesSet.Count == 0)
			{
				serviceItem.AddSKU(null);
			}
			else
			{
				//将属性值列表集合做笛卡尔积，为每一种组合生成一条SKU
				for (int i = 0; i < combinedSetLength; i++)
				{
					var tempList = new List<ServiceSKUPropertyValue>(propertyValuesSet.Count);
					var tempIndex = 1;

					foreach (var propertyValues in propertyValuesSet)
					{
						tempIndex *= propertyValues.Length;
						tempList.Add(propertyValues[(i / (combinedSetLength / tempIndex)) % propertyValues.Length]);
					}

					serviceItem.AddSKU(tempList.ToArray());
				}
			}
		}

		public ServiceOrder CreateServiceOrder(Hospital hospital, MembershipLevel membershipLevel, ICollection<ShoppingCartItem<ServiceItemSKU>> shoppingCart, string @operator)
		{
			if (shoppingCart.Count == 0)
			{
				throw new HangerdException("服务项列表为空");
			}

			var serviceOrder = new ServiceOrder(hospital, membershipLevel, @operator);

			foreach (var item in shoppingCart)
			{
				//增加订单行
				serviceOrder.AddOrderLine(new ServiceOrderLine(item.Item, item.Quantity));
			}

			//计算总额
			serviceOrder.CalculateTotalAmount();

			return serviceOrder;
		}
	}
}
